package com.amarsoft.tpf.connection.socket;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.concurrent.TimeoutException;

import com.amarsoft.tpf.TPFException;
import com.amarsoft.tpf.connection.BaseConnection;
import com.amarsoft.tpf.element.Transaction;
import com.amarsoft.tpf.encoder.AS400Encoder;

public class NioConnection extends BaseConnection{
	private SocketChannel so;
	private boolean blocked;
	private boolean closed;
	
	{
		blocked = true;
	}
	
	public NioConnection(){}

	public void open() throws IOException {
		String ip = getConnectionDesc().getProperties("host");
		String sPort = getConnectionDesc().getProperties("port");
		int port = Integer.parseInt(sPort);
		//String sConnectTimeout = getConnectionDesc().getProperties("connectTimeout");
		//int connectionTimeout = Integer.parseInt(sConnectTimeout);
		//String waitTimeout = getConnectionDesc().getProperties("waitTimeout");
		
		so = SocketChannel.open();
		so.configureBlocking(blocked);
		so.connect(new InetSocketAddress(ip, port));
		
		/*Socket socket = so.socket();
		socket.setSoTimeout(Integer.parseInt(waitTimeout));*/
	}

	public boolean isOpen() {
		return so.isOpen();
	}

	public void close() throws IOException {
		so.close();
		closed = true;
	}

	public boolean isClosed() throws IOException {
		return closed;
	}

	@Override
	protected void send(Transaction tran) throws IOException, TPFException,
			TimeoutException {
		ByteBuffer req = tran.getReqByteBuffer();
		req.flip();
		so.write(req);
	}

	@Override
	protected void receive(Transaction tran) throws IOException, TPFException,
			TimeoutException {
		int length = 9;
		ByteBuffer first = ByteBuffer.allocate(length);
		if(so.read(first) == 9){
			String sHeader = AS400Encoder.convertCp1388ToUnicode(first.array());
			length = Integer.parseInt(sHeader);
		}
		ByteBuffer remain = ByteBuffer.allocate(length);
		so.read(remain);
		
		first.flip();
		remain.flip();
		
		tran.getResByteBuffer().put(first);
		tran.getResByteBuffer().put(remain);
	}

	public void setBlocked(boolean blocked) {
		this.blocked = blocked;
	}
}
